﻿using System;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.Text;

namespace Felbot.Interaction {
    /// <summary>The Felbot Xml Document root for the standard file Users.fbx.</summary>
    [XmlRootAttribute("FelbotUsers", Namespace = "", IsNullable = false)]
    public class XmlUserRoot {
        /// <summary>Creates object for serialization.</summary>
        public XmlUserRoot() { }
        
        /// <summary>Gets the Users.fbx version.</summary>
        [XmlAttribute("version")]
        public double Version = 1.0;

        /// <summary>Gets the list of user entries.</summary>
        [XmlArray("users"), XmlArrayItem("entry", typeof(XmlEntry), IsNullable = true)]
        public List<XmlEntry> Users = new List<XmlEntry>();
    }

    /// <summary>The serializable <![CDATA[<entry>]]> tag. Contains information on the entry.</summary>
    [Serializable]
    public class XmlEntry {
        /// <summary>Creates object for serialization.</summary>
        public XmlEntry() { }

        /// <summary>Gets or sets name of the entry.</summary>
        [XmlAttribute("name")]
        public string Name;

        /// <summary>Gets or sets an enumeration defining the entry type.</summary>
        [XmlAttribute("type")]
        public XmlEntryType EntryType;

        /// <summary>Gets or sets the notes on the entry.</summary>
        [XmlArray("notes", IsNullable = true), XmlArrayItem("note", IsNullable = false)]
        public List<string> Notes;

        /// <summary>Gets the list of entry members in this entry.</summary>
        [XmlArray("members"), XmlArrayItem("entry", typeof(string))]
        public List<string> Members = new List<string>();

        /// <summary>Gets an object containing entry creation information.</summary>
        [XmlElement("created")]
        public XmlEntryEdit Created;

        /// <summary>Gets a list of objects containing entry edit information.</summary>
        [XmlArray("edits"), XmlArrayItem("edited", typeof(XmlEntryEdit))]
        public List<XmlEntryEdit> Edits = new List<XmlEntryEdit>();

        /// <summary>Gets an object controlling the entries access.</summary>
        [XmlElement("has", typeof(XmlEntryHas), IsNullable = true)]
        public XmlEntryHas Has;
    }

    /// <summary>The serializable<![CDATA[<created>]]> and <![CDATA[<edited>]]> tags. Contains information on the entries edits.</summary>
    [Serializable]
    public class XmlEntryEdit {
        /// <summary>Creates object for serialization.</summary>
        public XmlEntryEdit() { }
        
        internal XmlEntryEdit(string user, DateTime time) {
            By = user;
            Time = time;
        }

        /// <summary>Gets when the entry was edited or created.</summary>
        [XmlElement("time")]
        public DateTime Time;

        /// <summary>Gets who edited or created the entry.</summary>
        [XmlElement("by")]
        public string By;
    }

    /// <summary>The serializable <![CDATA[<has>]]> tag. Contains information on the entries access.</summary>
    [Serializable]
    public class XmlEntryHas {
        /// <summary>Creates object for serialization.</summary>
        public XmlEntryHas() { }

        /// <summary>Gets the list of flags the entry was given.</summary>
        [XmlArray("flags", IsNullable = true), XmlArrayItem("flag", IsNullable = false)]
        public List<string> Flags = new List<string>();
    }

    /// <summary>Specifies the type of the entry.</summary>
    public enum XmlEntryType {
        /// <summary>The entry contains other entries. todo: this may be phased out and all entries can be groups.</summary>
        Group = 2,
        /// <summary>The entry is not found in the database and was made for the purposes of checking cumulative flags for user access.</summary>
        Cumulative = 0,
        /// <summary>The entry represents all users whose name matches the specific regular expression or is equal to the specific name.</summary>
        User = 1,
        /// <summary>The entry represents all users who are logged on with the specific client.</summary>
        Client = 11,
        /// <summary>The entry represents all users who say the specific phrase.</summary>
        Phrase = 12,
        /// <summary>The entry represents all users who have a specific level, win amount, or win percentage.</summary>
        GameStat = 13,
        /// <summary>The entry represents all members of a WarCraft III Clan who have that clan's tag.</summary>
        Wc3Clan = 21,
        /// <summary>The entry represents all members of the bot's current WarCraft III Clan who have the specified clan rank.</summary>
        Wc3ClanRank = 22
    }
}
